package com.zlyx.easy.security.defaults.filter;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.RequestMatcher;

import com.zlyx.easy.core.utils.StringUtils;
import com.zlyx.easy.security.authentication.token.AuthenticationToken;

/**
 * <p>
 * 默认授权过滤器
 * </p>
 *
 * @author 赵光
 * @version v1.0
 */
public class DefaultAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

	protected Logger logger = LoggerFactory.getLogger(SecurityConfigurerAdapter.class);

	public static final String OAUTH_LOGIN_PATH = "/oauth/login";

	public DefaultAuthenticationFilter() {
		this(OAUTH_LOGIN_PATH);
	}

	public DefaultAuthenticationFilter(String defaultFilterProcessesUrl) {
		super(defaultFilterProcessesUrl);
	}

	public DefaultAuthenticationFilter(RequestMatcher requiresAuthenticationRequestMatcher, List<String> grantTypes) {
		super(requiresAuthenticationRequestMatcher);
	}

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
			throws AuthenticationException, IOException, ServletException {
		// 判断登录授权类型
		String grantType = request.getParameter(OAuth2Utils.GRANT_TYPE);
		logger.debug("grantType = {} ", grantType);

		// 用于登录的客户端id
		String clientId = request.getParameter(OAuth2Utils.CLIENT_ID);
		if (StringUtils.isBlank(clientId)) {
			throw new AuthenticationServiceException("client_id is null");
		}

		// 取出用于登录的唯一标识码，可以是钉钉扫码获取的code、微信扫码获取的code、手机验证码、邮箱验证码
		Object principal = request.getParameter("principal");
		if (principal == null) {
			throw new AuthenticationServiceException("principal is null");
		}

		AuthenticationToken authenticationToken = new AuthenticationToken(principal, grantType, clientId);

		// 将请求参数全部塞到authenticationToken中备用
		authenticationToken.setParams(request.getParameterMap());
		authenticationToken.setDetails(authenticationDetailsSource.buildDetails(request));
		return this.getAuthenticationManager().authenticate(authenticationToken);
	}
}
